unit config;

{$mode delphi}

interface

uses
  // RTL, FCL, LCL
  Classes, SysUtils, Math, IniFiles, Forms,
  // TesteDeVisao
  constants;

type
  { TTestConfig }

  TTestConfig = class(TObject)
  private
    function GetArcminsPerPixel: Double;
    function GetMaxVA: Cardinal;
    function GetPixelsPerMilimeter: Double;
  public
    { inputs }
    ScreenDistance: Cardinal;
    BarSize: Cardinal;
    BarSizeInPixels: Cardinal;
    { Other config info }
    HashDaSenha: string;
    Usuarios: TStringList;
    UsuarioAtual: string;
    Path: string;
    // Methods
    constructor Create;
    destructor Destroy; override;
    procedure LoadFromFile;
    procedure SaveToFile;
    function GetConfigFilePath: string;
    function GetDatabasePath: string;
    function GetVisualAcuity(ABestFitRow: Byte): Cardinal;
    property ArcminsPerPixel: Double read GetArcminsPerPixel;
    property PixelsPerMilimeter: Double read GetPixelsPerMilimeter;
    property MaxVA: Cardinal read GetMaxVA;
  end;

var
  gTestConfig: TTestConfig;

implementation

{$ifdef Windows}
uses Windows;
{$endif}

{ TTestConfig }

function TTestConfig.GetArcminsPerPixel: Double;
begin
  Result := arctan(BarSize / (ScreenDistance * BarSizeInPixels)) * 180 * 60 / Pi;
end;

{
  Returns the Maximum calculable Visual Acuity with the
  current configurations in Snellen Fraction Notation, as
  20 / MaxVA
}
function TTestConfig.GetMaxVA: Cardinal;
begin
  Result := Round(20 * ArcminsPerPixel);
end;

function TTestConfig.GetPixelsPerMilimeter: Double;
begin
  Result := 0.0;

{$ifdef Windows}
  // ToDo: In Windows Vista use SetProcessDPIAware() to get real DPI
  // GetDeviceCaps returns PixelsPerInch, so we convert to milimeters
  Result := GetDeviceCaps(GetDC(0), LOGPIXELSX) / 25.4;
{$endif}

  // Just use a good default 96 DPI if nothing was found
  if Result = 0.0 then Result := 96 / 25.4;
end;

constructor TTestConfig.Create;
begin
  inherited Create;

  Usuarios := TStringList.Create;

  {$ifdef Linux}
  //Path := '/home/professor/Programas/brtablet/testedevisao/';
  Path := '/media/psf/Home/Documents/brtablet/testedevisao/';
  {$endif}

  // Defaults
  BarSizeInPixels := 500;

  LoadFromFile();
end;

destructor TTestConfig.Destroy;
begin
  SaveToFile();

  Usuarios.Free;

  inherited Destroy;
end;

procedure TTestConfig.LoadFromFile;
var
  MyFile: TIniFile;
  Str: string;
begin
  Str := GetConfigFilePath;
  MyFile := TIniFile.Create(Str);
  try
    HashDaSenha := MyFile.ReadString(SectionAdmin, IdentSenha, '');
    MyFile.ReadSection(SectionUsers, Usuarios);
    Str := Usuarios.Text;// debug
  finally
    MyFile.Free;
  end;
end;

procedure TTestConfig.SaveToFile;
var
  MyFile: TIniFile;
  Str: string;
  i: Integer;
begin
  Str := GetConfigFilePath;
  MyFile := TIniFile.Create(Str);
  try
    MyFile.WriteString(SectionAdmin, IdentSenha, HashDaSenha);

    MyFile.EraseSection(SectionUsers);
    Str := Usuarios.Strings[0]; // debug
    for i := 0 to Usuarios.Count - 1 do
      MyFile.WriteString(SectionUsers, Usuarios.Strings[i], ' ');
  finally
    MyFile.Free;
  end;
end;

function TTestConfig.GetConfigFilePath: string;
begin
  {$ifdef Windows}
    Result := ExtractFilePath(Application.ExeName) + 'testedevisao.ini';
  {$else}
    Result := GetAppConfigFile(True);
  {$endif}
end;

function TTestConfig.GetDatabasePath: string;
begin
  {$ifdef Windows}
    Result := ExtractFilePath(Application.ExeName) + 'historico.dat';
  {$else}
    //???
  {$endif}
end;

function TTestConfig.GetVisualAcuity(ABestFitRow: Byte): Cardinal;
var
  lC_OpeningSize: Cardinal; // In pixels
  lArcmins: Double;
begin
  lC_OpeningSize := OptotypeResolutions[ABestFitRow];
  lArcmins := lC_OpeningSize * ArcminsPerPixel;
  Result := Round(lArcmins * 20);
end;

initialization

  gTestConfig := TTestConfig.Create;

finalization

  gTestConfig.Free;

end.

